package tr.com.netgis.util;

import java.util.Collections;
import java.util.List;

import tr.com.netgis.pojo.NGLocation;
import tr.com.netgis.util.RotatingNGLocation.LOC_SEND_STATUS;


public abstract class AStatusSpeedStrategy implements StatusSpeedStrategy {

	public AStatusSpeedStrategy(RotatingNGLocation locations) {
		super();
	}
	
	public AStatusSpeedStrategy() {
		super();
	}
	
	@Override
	public Status determineStatus(NGLocation currentLocation, RotatingNGLocation rLocations) {
		List<NGLocation> locations = rLocations.toList();
		Collections.sort(locations);
		/*NGLocation previousLocation = getPreviousLocation(currentLocation, locations);
		if (previousLocation == null)
			return Status.UYGULAMA_ACILDI;
		*/
		//Daha öncekiler gönderilmediyse bu location uygulama açıldı olarak gönder
		if (rLocations.getLocationSendStatus().equals(LOC_SEND_STATUS.NO_ACTION) || 
				rLocations.getLocationSendStatus().equals(LOC_SEND_STATUS.FALSE)) {
			LOC_SEND_STATUS atLeastOneLocSent = LOC_SEND_STATUS.FALSE;
			for (int i = 0; i < locations.size(); i++) {
				if (locations.get(i).isSent()) {
					atLeastOneLocSent = LOC_SEND_STATUS.TRUE;
					break;
				}
			}
			rLocations.setLocationSendStatus(atLeastOneLocSent);
		}
		/*
		if (rLocations.getLocationSendStatus().equals(LOC_SEND_STATUS.FALSE) || locations.size() == 1)
			return Status.UYGULAMA_ACILDI;
		*/
		if (locations.size() == 1)
			return Status.UYGULAMA_ACILDI;
		/*
		if (stopped(currentLocation, locations)) {
			return Status.DURDU;
		}
		*/
		//hızları zaten, önceden ortalamaya göre hesaplıyoruz
		if (currentLocation.getSpeed() < Constants.eV)
			return Status.DURDU;
		else {
			return Status.HAREKET_EDIYOR;
		}
		
	}
	
	/**
	 * şimdilik hız hesaplama bir önceki konuma göre yapılacak Last2Location gibi yapılıyor
	 */
	@Override
	public float calculateSpeed(NGLocation currentLocation, RotatingNGLocation rLocations) {
		List<NGLocation> locations = rLocations.toList();
		NGLocation previousLocation = getPreviousLocation(currentLocation, locations);
		return Utility.speed(previousLocation, currentLocation);
	}
	
	protected NGLocation getPreviousLocation (NGLocation currentLocation, List<NGLocation> locations){
		if (!Utility.isNotEmpty(locations))
			return null;
		Collections.sort(locations);
		for (int i = locations.size() - 1 ; i >= 0; i--) {
			if (locations.get(i).equals(currentLocation))
				continue;
			return locations.get(i);
		}
		return null;
	}
	
	/**
	 * Locations' speed property must be set before.
	 * @param currentLocation
	 * @param locations
	 * @return
	 */
	protected boolean stopped (NGLocation currentLocation, List<NGLocation> locations){
		boolean durdu = true;
		int n = locations.size();
		float eV = Constants.eV;
		if (n > 3) {
		     for (int i = 0; i < n; i++) {
		         if (locations.get(i).getSpeed() > eV) {
		              durdu = false;
		              break;
		         }
		     }
		 
		     float vAvarage = Utility.speed(locations.get(0), locations.get(n - 1));
		     
		     if (vAvarage > eV) {
		    	 durdu = false;
		     }
		} else {
		     //son konuma bak, yani sunucuya post edilecek konum bilgisine
		     durdu = currentLocation.getSpeed() < eV;
		}		
		return durdu;
	}
	
}
